package com.ja.openchat.ui.chat.adapter.viewholder;

import android.content.Context;
import android.content.Intent;
import android.text.TextUtils;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.widget.CheckBox;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;

import androidx.annotation.Nullable;
import androidx.core.util.Pair;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.afollestad.materialdialogs.MaterialDialog;
import com.ja.openchat.R;
import com.ja.openchat.ui.chat.ConversationFragment;
import com.ja.openchat.ui.chat.ForwardActivity;
import com.ja.openchat.ui.chat.adapter.ConversationMessageAdapter;
import com.ja.openchat.ui.chat.adapter.GroupAdAdapter;
import com.ja.openchat.ui.chat.annotation.MessageContextMenuItem;
import com.ja.openchat.ui.chat.listener.OnDeleteDialogListener;
import com.ja.openchat.views.MessageReactionView;
import com.ja.openchat.views.SpaceItemDecoration;
import com.ja.openchat.views.UserAvatarView;
import com.ja.openchat.views.progressview.CircleProgressView;
import com.lxj.xpopup.util.XPopupUtils;
import com.zy.openchat.Constants;
import com.zy.openchat.core.manager.TelegramManager;
import com.zy.openchat.core.model.message.ChatInfo;
import com.zy.openchat.core.model.message.InlineKeyboardButton;
import com.zy.openchat.core.model.message.MessageInfo;
import com.zy.openchat.core.model.message.UiMessage;
import com.zy.openchat.core.model.user.UserInfo;
import com.zy.openchat.util.Common;
import com.zy.openchat.util.TimeUtils;

import java.util.ArrayList;
import java.util.List;

import butterknife.BindView;
import butterknife.OnClick;
import butterknife.Optional;
import io.reactivex.functions.Consumer;

/**
 * 普通消息
 */
public abstract class NormalMessageContentViewHolder extends MessageContentViewHolder {
    @BindView(R.id.portraitView)
    UserAvatarView portraitView;
    @BindView(R.id.errorLinearLayout)
    LinearLayout errorLinearLayout;
    @BindView(R.id.nameTextView)
    TextView nameTextView;
    @BindView(R.id.progressBar)
    ProgressBar progressBar;
    @Nullable
    @BindView(R.id.waveProgress)
    CircleProgressView waveProgress;
    @Nullable
    @BindView(R.id.progressLayout)
    View progressLayout;
    @BindView(R.id.checkbox)
    CheckBox checkBox;
    @BindView(R.id.groupReceiptFrameLayout)
    @Nullable
    FrameLayout groupReceiptFrameLayout;
    @BindView(R.id.deliveryProgressBar)
    @Nullable
    ProgressBar deliveryProgressBar;
    @BindView(R.id.readProgressBar)
    @Nullable
    ProgressBar readProgressBar;

    @BindView(R.id.message_time)
    @Nullable
    TextView messageTime;

    @BindView(R.id.message_status)
    @Nullable
    ImageView messageStatus;

    @BindView(R.id.notificationErrorTextView)
    @Nullable
    TextView notificationErrorTextView;
    @BindView(R.id.chatReadTag)
    @Nullable
    View chatReadTag;
    @BindView(R.id.chatReadNum)
    @Nullable
    TextView chatReadNum;

    @BindView(R.id.adRecyclerView)
    @Nullable
    RecyclerView adRecyclerView;

    @BindView(R.id.messageReactionView)
    @Nullable
    MessageReactionView messageReactionView;

    @BindView(R.id.ivError)
    @Nullable
    ImageView ivError;

    public NormalMessageContentViewHolder(ConversationFragment fragment, RecyclerView.Adapter adapter, View itemView) {
        super(fragment, adapter, itemView);
    }

    @Override
    public void onBind(UiMessage message, int position) {
        super.onBind(message, position);
        this.message = message;
        this.position = position;

        setSenderAvatar(message);
        setSenderName(message.message);
        setSendStatus(message.message);
        doBurnAfterReading(message.message);
        doGroupAd(message.message);
        try {
            onBind(message);
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (message.isFocus) {
            highlightItem(itemView, message);
        }

        if(messageTime!=null){
            messageTime.setText(TimeUtils.getMsgFormatHMTime(message.message.date*1000));
        }
        if(messageReactionView!=null){
            messageReactionView.setMessage(message);
        }
    }



    @Override
    public void onBind(UiMessage message, int position, int payloadType) {
        if(payloadType == Constants.Notify_User_Name_Type){
            setSenderName(message.message);
        }else if(payloadType == Constants.Notify_Message_Reaction){
            if(messageReactionView!=null){
                messageReactionView.setMessage(message);
            }
        }else{
            super.onBind(message, position, payloadType);
        }


    }

    private void doGroupAd(MessageInfo messageInfo){
        if(adRecyclerView==null){
            return;
        }
        if(messageInfo==null||messageInfo.reply_markup==null|| Common.isEmpty(messageInfo.reply_markup.rows)){
            adRecyclerView.setVisibility(View.GONE);
            return;
        }
        List<InlineKeyboardButton> buttons = messageInfo.reply_markup.getTemp();
        GridLayoutManager manager = new GridLayoutManager(fragment.getContext(),2);
        if(buttons.size()%2!=0){
            manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                @Override
                public int getSpanSize(int position) {
                    return position == buttons.size()-1?2:1;
                }
            });
        }
        adRecyclerView.setLayoutManager(manager);
        if(adRecyclerView.getAdapter()!=null&&adRecyclerView.getAdapter() instanceof GroupAdAdapter){
            GroupAdAdapter adAdapter = (GroupAdAdapter)adRecyclerView.getAdapter();
            adAdapter.setNewData(buttons);
        }else{
            GroupAdAdapter adAdapter = new GroupAdAdapter(buttons);
            adRecyclerView.setAdapter(adAdapter);
        }
        if(adRecyclerView.getItemDecorationCount()>0){
            adRecyclerView.removeItemDecoration(adRecyclerView.getItemDecorationAt(0));
        }
        adRecyclerView.addItemDecoration(new SpaceItemDecoration(XPopupUtils.dp2px(fragment.getContext(),5),false,SpaceItemDecoration.GRIDLAYOUT));
        adRecyclerView.setVisibility(View.VISIBLE);
    }

    private void doBurnAfterReading(MessageInfo messageInfo){
        if(messageInfo==null||(messageInfo.ttl<=0&&messageInfo.barInfo==null)){
            if(chatReadNum!=null){
                chatReadNum.setVisibility(View.GONE);
            }
            return;
        }
        int countDownSeconds = messageInfo.barInfo!=null?messageInfo.barInfo.countDown:messageInfo.ttl;
        if(chatReadNum!=null) {
            chatReadNum.setVisibility(View.VISIBLE);
        }
        if(messageInfo.isOutgoing()){
            if(chatReadNum!=null) {
                chatReadNum.setText(String.format("%ds", countDownSeconds));
            }
        }else{
            String value = TelegramManager.getTelegramManager().apppendBurnTask(messageInfo, new Consumer<String>() {
                @Override
                public void accept(String s) throws Exception {
                    if(chatReadNum!=null) {
                        chatReadNum.setText(s);
                    }
                }
            });
            if(chatReadNum!=null) {
                chatReadNum.setText(value);
            }
        }

    }


    protected abstract void onBind(UiMessage message);

    /**
     * when animation finish, do not forget to set {@link UiMessage#isFocus} to {@code true}
     *
     * @param itemView the item view
     * @param message  the message to highlight
     */
    protected void highlightItem(View itemView, UiMessage message) {
        if(message.isFocus){
            message.isFocus = false;
        }
        Animation animation = new AlphaAnimation((float) 0.35, (float) 0.15);
        itemView.setBackgroundColor(itemView.getResources().getColor(R.color.colorPrimary));
        animation.setRepeatCount(1);
        animation.setDuration(500);
        animation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                itemView.setBackground(null);
                message.isFocus = false;
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
        itemView.startAnimation(animation);
    }

    // TODO 也用注解来做？
    public boolean checkable(UiMessage message) {
        return true;
    }

    @Optional
    @OnClick(R.id.errorLinearLayout)
    public void onRetryClick(View itemView) {
        new MaterialDialog.Builder(fragment.getContext())
            .content(fragment.getString(R.string.resend_question_text))
            .negativeText(fragment.getString(R.string.cancle_text))
            .positiveText(fragment.getString(R.string.resend_text))
            .onPositive((dialog, which) -> fragment.resendMessage(message.message))
            .build()
            .show();
    }

    @Optional
    @OnClick(R.id.groupReceiptFrameLayout)
    public void OnGroupMessageReceiptClick(View itemView) {
        ((ConversationMessageAdapter) adapter).onGroupMessageReceiptClick(message.message);
    }

    @MessageContextMenuItem(tag = MessageContextMenuItemTags.TAG_RECALL, priority = 5)
    public void recall(View itemView, UiMessage message) {
        messageViewModel.recallMessage(message.message);
    }

    @MessageContextMenuItem(tag = MessageContextMenuItemTags.TAG_DELETE, confirm = false, priority = 4)
    public void removeMessage(View itemView, UiMessage message) {
        fragment.deleteMessages(new OnDeleteDialogListener() {
            @Override
            public void onDeleteRevoke(boolean isJustMeDelete) {
                if(isJustMeDelete){
                    messageViewModel.deleteMessage(message.message);
                }else{
                    messageViewModel.deleteOrRevoke(message.message,true);
                }
            }
        });

    }

    @MessageContextMenuItem(tag = MessageContextMenuItemTags.TAG_MULTI_CHECK, priority = 7)
    public void checkMessage(View itemView, UiMessage message) {
        fragment.toggleMultiMessageMode(message);
    }

    @MessageContextMenuItem(tag = MessageContextMenuItemTags.TAG_FAV, priority = 6)
    public void favMessage(View itemView, UiMessage message) {
        List<UiMessage> messages = new ArrayList<>();
        messages.add(message);
        fragment.favMessageMode(messages);
    }

    @MessageContextMenuItem(tag = MessageContextMenuItemTags.TAG_FORWARD, priority = 3)
    public void forwardMessage(View itemView, UiMessage message) {
        Intent intent = new Intent(fragment.getContext(), ForwardActivity.class);
        if(message.message.reply_markup!=null&&!Common.isEmpty(message.message.reply_markup.getTemp())){
            intent.putExtra("only_chat_id",message.message.chat_id);
        }
        intent.putExtra("message", message.message);
        fragment.startActivity(intent);
    }


    @MessageContextMenuItem(tag = MessageContextMenuItemTags.TAG_QUOTE, priority = 1)
    public void quoteMessage(View itemView, UiMessage message) {
        fragment.getConversationInputPanel().quoteMessage(message.message);
    }

    @Override
    public Pair<String,Integer> contextMenuTitle(Context context, String tag) {
        String title = context.getString(R.string.not_set);
        int resId = View.NO_ID;
        switch (tag) {
            case MessageContextMenuItemTags.TAG_RECALL:
                title = context.getString(R.string.revoke_text);
                resId = R.mipmap.menu_chexiao;
                break;
            case MessageContextMenuItemTags.TAG_DELETE:
                title = context.getString(R.string.delete_text);
                resId = R.mipmap.menu_shanchu1;
                break;
            case MessageContextMenuItemTags.TAG_MULTI_CHECK:
                title = context.getString(R.string.multiple_choice);
                resId = R.mipmap.menu_duoxuankuang;
                break;
            case MessageContextMenuItemTags.TAG_FORWARD:
                title = context.getString(R.string.forward_text);
                resId = R.mipmap.menu_zhuanfa;
                break;
            case MessageContextMenuItemTags.TAG_FAV:
                title = context.getString(R.string.collect_text);
                resId = R.mipmap.menu_shoucang1;
                break;
            case MessageContextMenuItemTags.TAG_QUOTE:
                title = context.getString(R.string.quote_text);
                resId = R.mipmap.menu_quote;
                break;
            case MessageContextMenuItemTags.TAG_VOICE_TRANSFER_TEXT:
                title = context.getString(R.string.convert_text);
                resId = R.mipmap.menu_turn_text;
                break;
            case MessageContextMenuItemTags.TAG_TRANSLATION:
                title = context.getString(R.string.translate_text);
                resId = R.mipmap.menu_translation;
                break;
            default:
                break;
        }
        return new Pair<String,Integer>(title,resId);
    }

    @Override
    public String contextConfirmPrompt(Context context, String tag) {
        String title = context.getString(R.string.not_set);
        switch (tag) {
            case MessageContextMenuItemTags.TAG_DELETE:
                title = context.getString(R.string.confirm_delete_this_message);
                break;
            default:
                break;
        }
        return title;
    }

    @Override
    public boolean contextMenuItemFilter(UiMessage uiMessage, String tag) {
        MessageInfo message = uiMessage.message;
        if(message!=null&&(message.ttl>0||(message.barInfo!=null&&message.barInfo.countDown>0))){
            return true;
        }
        ChatInfo chatInfo = TelegramManager.getTelegramManager().getTgData().chatInfo(message.chat_id);
        if (MessageContextMenuItemTags.TAG_RECALL.equals(tag)) {
            if(chatInfo!=null&&chatInfo.isGroup()){
                return !message.isOutgoing()||!message.isMessageCanRevoke();
            }else{
                return !message.isMessageCanRevoke();
            }

        }else if(MessageContextMenuItemTags.TAG_FAV.equals(tag)){
            return message.isFromMyFovChat()||message.messageType == TelegramManager.MessageType.MessageType_Animation;
        }else if(MessageContextMenuItemTags.TAG_FORWARD.equals(tag)){
            if(chatInfo!=null&&chatInfo.isSecretChat()){
                return true;
            }else{
                return false;
            }
        }

        return false;
    }

    private void setSenderAvatar(UiMessage uiMessage) {
        if(uiMessage==null){
            return;
        }
        MessageInfo item = uiMessage.message;
        UserInfo userInfo = UserInfo.getUserInfo(item.sender_user_id());
        if(userInfo==null){
            uiMessage.isAvaterDownloaded = false;
            return;
        }
        portraitView.showUser(userInfo);
        ChatInfo chatInfo = TelegramManager.getTelegramManager().getTgData().chatInfo(item.chat_id);
        if(chatInfo != null && chatInfo.isGroup() && direction != 0){
            portraitView.setVisibility(View.VISIBLE);
        }else{
            portraitView.setVisibility(View.GONE);
        }
        if(userInfo.profile_photo!=null&&!userInfo.profile_photo.isSmallPhotoDownloaded()){
            uiMessage.isAvaterDownloaded = false;
            TelegramManager.getTelegramManager().downloadFile(String.valueOf(userInfo.id), message.message.getVideoFileId(), 0, TelegramManager.FileType.FileType_Photo);
        }else{
            uiMessage.isAvaterDownloaded = true;
        }
    }





    private void setSenderName(MessageInfo item) {
        if (UserInfo.getUserInfo().id == message.message.sender_user_id()) {
            nameTextView.setVisibility(View.GONE);
            return;
        }
        ChatInfo chatInfo = TelegramManager.getTelegramManager().getTgData().chatInfo(item.chat_id);
        if(chatInfo!=null&&chatInfo.isGroup()){
            showGroupMemberAlias(message.message.sender_user_id());
        }
    }

    private void showGroupMemberAlias(long sender) {

        nameTextView.setVisibility(View.VISIBLE);
        String nickName = messageViewModel!=null?messageViewModel.getGroupNickNameByUserId(sender):null;
        nameTextView.setText(TextUtils.isEmpty(nickName)?UserInfo.userDisplayName(sender):nickName);
        nameTextView.setTag(sender);
    }



    protected void setSendStatus(MessageInfo item) {
        TelegramManager.MessageSendState sentStatus = item.sendState();
        if(messageStatus!=null) messageStatus.setVisibility(View.GONE);
        if(chatReadTag!=null){
            if(item.barInfo==null&&item.ttl<=0){
                chatReadTag.setVisibility(View.GONE);
            }else{
                chatReadTag.setVisibility(View.VISIBLE);
            }
        }
        if (!item.isOutgoing()) {
            if(progressLayout!=null){
                progressLayout.setVisibility(View.GONE);
            }
            if(chatReadTag!=null) {
                chatReadTag.setActivated(true);
            }
            return;
        }
        if(item.isRead()){
            if(chatReadTag!=null) {
                chatReadTag.setActivated(true);
            }
            messageStatus.setImageResource(R.drawable.icon_message_read_status_pre);
            messageStatus.setVisibility(View.VISIBLE);
        }else if(item.sendState() == TelegramManager.MessageSendState.MessageSendState_Success){
            if(chatReadTag!=null) {
                chatReadTag.setActivated(false);
            }
            if(progressLayout!=null){
                progressLayout.setVisibility(View.GONE);
            }
            messageStatus.setImageResource(R.drawable.icon_message_read_status_def);
            messageStatus.setVisibility(View.VISIBLE);
        }

        if(notificationErrorTextView!=null){
            notificationErrorTextView.setVisibility(View.GONE);
        }
        if (sentStatus == TelegramManager.MessageSendState.MessageSendState_Pending) {
            if(progressLayout!=null){
                progressLayout.setVisibility(View.VISIBLE);
            }
            if(waveProgress!=null){
                waveProgress.setVisibility(View.VISIBLE);
                waveProgress.setProgress(item.getUploadingProgress());
            }
            progressBar.setVisibility(View.VISIBLE);

            errorLinearLayout.setVisibility(View.GONE);
            return;
        } else if (sentStatus == TelegramManager.MessageSendState.MessageSendState_Fail) {
            if(progressLayout!=null) {
                progressLayout.setVisibility(View.GONE);
            }
            progressBar.setVisibility(View.GONE);
            errorLinearLayout.setVisibility(View.VISIBLE);
            if(notificationErrorTextView!=null&&item.getSending_state()!=null&&!TextUtils.isEmpty(item.getSending_state().error_message)){
                notificationErrorTextView.setVisibility(View.VISIBLE);
                String errorMessage = item.getSending_state().error_message;
                if("YOU_BLOCKED_USER".equals(errorMessage)){
                    notificationErrorTextView.setText(R.string.has_been_blacklisted);
                }else if("USER_PRIVACY_RESTRICTED".equals(errorMessage)){
                    notificationErrorTextView.setText(R.string.refuses_to_talk_to_strangers);
                }else{
                    notificationErrorTextView.setText(errorMessage);
                }

            }
            return;
        } else if (sentStatus == TelegramManager.MessageSendState.MessageSendState_Success) {
            if(progressLayout!=null) {
                progressLayout.setVisibility(View.GONE);
            }
            progressBar.setVisibility(View.GONE);
            errorLinearLayout.setVisibility(View.GONE);
        }

    }
}
